/*
 * 项目名称:    wms-server-jeecg
 * 创建人员:    gongwenkai
 * 创建时间:    2023-09-26
 */
package org.jeecg.modules.flow.callback.outbound.task;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.modules.business.doc.outbound.entity.WmsOutReceipt;
import org.jeecg.modules.business.doc.outbound.entity.WmsOutReceiptMaterial;
import org.jeecg.modules.business.doc.outbound.entity.vo.OutBoundReceiptSaveVO;
import org.jeecg.modules.business.doc.outbound.service.IWmsOutReceiptMaterialService;
import org.jeecg.modules.business.doc.outbound.service.IWmsOutReceiptService;
import org.jeecg.modules.business.outbound.entity.WmsOutReceiptTask;
import org.jeecg.modules.business.outbound.entity.WmsOutReceiptTaskMaterial;
import org.jeecg.modules.business.outbound.service.IWmsOutReceiptTaskMaterialService;
import org.jeecg.modules.business.outbound.service.IWmsOutReceiptTaskService;
import org.jeecg.modules.flow.callback.enums.DocumentStatusEnum;
import org.jeecg.modules.flow.callback.enums.OutboundStatusEnum;
import org.jeecg.modules.flow.callback.outbound.util.CommonOutboundUtil;
import org.jeecg.modules.flow.record.entity.WmsFlowRecord;
import org.jeecg.modules.flow.sys.common.BaseCustomBeanRun;
import org.jeecg.modules.flow.sys.entity.dto.BaseFlowDto;
import org.jeecg.modules.flow.sys.entity.dto.WorkFlowInfoDto;
import org.jeecg.modules.flow.sys.service.WorkFlowService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 纵剪叫纸筒 出库 回调Bean（已作废）
 *
 * @author gongwenkai
 * @version 1.0.0
 * @since 2023-09-26
 */
@Deprecated
@RequiredArgsConstructor
@Component
public class OutBoundTaskZJJZTOutBean<T> extends BaseCustomBeanRun<T> {


    private final IWmsOutReceiptTaskService wmsOutReceiptTaskService;

    private final IWmsOutReceiptTaskMaterialService wmsOutReceiptTaskMaterialService;

    private final IWmsOutReceiptService wmsOutReceiptService;

    private final IWmsOutReceiptMaterialService wmsOutReceiptMaterialService;

    private final WorkFlowService workFlowService;

    private final CommonOutboundUtil commonOutboundUtil;

    /**
     * 业务逻辑 出库任务提交
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void actureRun() {
        BaseFlowDto baseFlowDto = this.getBaseFlowDto();
        String taskId = baseFlowDto.getInfoId();
        //自动创建出库单，草稿状态
        //拿到创建出库单的数据
        baseFlowDto.translateClass(JSONObject.class);
        JSONObject jsonData= (JSONObject)baseFlowDto.getData();
        if(jsonData!=null){
            Boolean fromReceiptOrderFlag = jsonData.getBoolean("fromReceiptOrderFlag");
            if(fromReceiptOrderFlag!=null&&fromReceiptOrderFlag==true){
                //如果是从出库单流转过来的
                //判断并更新任务信息和状态
                Boolean flag = updateTaskMaterial(jsonData.getString("receiptId"));
                //如果已经全部出库，流转到下一个节点
                if(!flag){
                    baseFlowDto.setRunThenStop(true);
                }
            }else{
                //自动创建出库单
                autoCreateOrder(taskId);
                baseFlowDto.setRunThenStop(true);
            }
        }
        // 当前前端调用业务需要你返回的
        baseFlowDto.setResult(Result.OK());
        // id是保存业务记录的id。用于生成业务流程信息记录
        baseFlowDto.setInfoId(taskId);
    }


    /**
     * 自动创建出库单 草稿状态
     * @param taskId
     */
    public void autoCreateOrder(String taskId) {

        WmsOutReceiptTask receiptTask = wmsOutReceiptTaskService.getById(taskId);
        if(receiptTask==null){
            throw new JeecgBootException("出库任务不存在");
        }
        List<WmsOutReceiptTaskMaterial> receiptTaskMaterialList = wmsOutReceiptTaskMaterialService.list(new LambdaUpdateWrapper<WmsOutReceiptTaskMaterial>()
                .eq(WmsOutReceiptTaskMaterial::getWmsOutReceiptTaskId, taskId)
        );
        WmsOutReceipt wmsOutReceipt = new WmsOutReceipt();
        wmsOutReceipt.setSysOrgCode(receiptTask.getSysOrgCode());
        wmsOutReceipt.setOrganization(receiptTask.getOrganization());
        wmsOutReceipt.setDocumentType(receiptTask.getDocumentType());
        wmsOutReceipt.setDocumentCode((String) FillRuleUtil.executeRule("ck_rule", null));
        wmsOutReceipt.setOwnerType(receiptTask.getOwnerType());
        wmsOutReceipt.setBusinessDate(null);
        wmsOutReceipt.setOwner(receiptTask.getOwner());
        wmsOutReceipt.setWarehouseDirection(receiptTask.getWarehouseDirection());
        wmsOutReceipt.setCustomer(receiptTask.getCustomer());
        wmsOutReceipt.setDocumentStatus(null);
        wmsOutReceipt.setWmsBasicWarehouseGroupId(receiptTask.getWmsBasicWarehouseGroupId());
        wmsOutReceipt.setRemark(null);
        wmsOutReceipt.setWarehouseKeeper(receiptTask.getWarehouseKeeper());
        wmsOutReceipt.setOutDate(new Date());
        wmsOutReceipt.setHasChild(1);
        wmsOutReceipt.setWmsOutReceiptTaskId(receiptTask.getId());

        List<WmsOutReceiptMaterial> wmsOutReceiptMaterialList = receiptTaskMaterialList.stream().map(o -> {
            WmsOutReceiptMaterial wmsOutReceiptMaterial = new WmsOutReceiptMaterial();
            wmsOutReceiptMaterial.setSysOrgCode(o.getSysOrgCode());
            wmsOutReceiptMaterial.setWmsBasicMaterialId(o.getWmsBasicMaterialId());
            wmsOutReceiptMaterial.setBatchCode(o.getBatchCode());
            wmsOutReceiptMaterial.setPayableQuantity(o.getPlanQuantity());
            wmsOutReceiptMaterial.setOutboundQuantity(o.getPlanQuantity());
            wmsOutReceiptMaterial.setWmsBasicWarehouseId(o.getWmsBasicWarehouseId());
            wmsOutReceiptMaterial.setWmsBasicWarehouseAreaId(o.getWmsBasicWarehouseAreaId());
            wmsOutReceiptMaterial.setWmsBasicWarehouseAreaLocationId(o.getWmsBasicWarehouseAreaLocationId());
            wmsOutReceiptMaterial.setAssistQuantity(Objects.isNull(o.getAssistQuantity()) ? null : o.getAssistQuantity());
            wmsOutReceiptMaterial.setSteelCoilNumber(o.getSteelCoilNumber());
            wmsOutReceiptMaterial.setOutsideDiameter(ObjectUtil.isEmpty(o.getOutsideDiameter()) ? null : o.getOutsideDiameter());
            wmsOutReceiptMaterial.setWidth(ObjectUtil.isEmpty(o.getWidth()) ? null : o.getWidth());
            wmsOutReceiptMaterial.setLength(ObjectUtil.isEmpty(o.getLength()) ? null : o.getLength());
            wmsOutReceiptMaterial.setThickness(ObjectUtil.isEmpty(o.getThickness()) ? null : o.getThickness());
            wmsOutReceiptMaterial.setShopSign(o.getShopSign());
            wmsOutReceiptMaterial.setAppearanceGrade(o.getAppearanceGrade());
            wmsOutReceiptMaterial.setIronLoss(o.getIronLoss());
            wmsOutReceiptMaterial.setMeasuredThickness(Objects.isNull(o.getMeasuredThickness()) ? null : o.getMeasuredThickness());
            wmsOutReceiptMaterial.setMeasuredIronLoss(o.getMeasuredIronLoss());
            wmsOutReceiptMaterial.setScore(o.getScore());
            wmsOutReceiptMaterial.setOriginalWeight(Objects.isNull(o.getOriginalWeight()) ? null : o.getOriginalWeight());
            wmsOutReceiptMaterial.setMeasuredWeight(Objects.isNull(o.getMeasuredWeight()) ? null : o.getMeasuredWeight());
            wmsOutReceiptMaterial.setVehicle(null);
            wmsOutReceiptMaterial.setSerialNumber(o.getSerialNumber());
            wmsOutReceiptMaterial.setSaleOrderNumber(o.getSaleOrderNumber());
            wmsOutReceiptMaterial.setSaleOrderLineNumber(o.getSaleOrderLineNumber());
            wmsOutReceiptMaterial.setProductNumber(o.getProductNumber());
            wmsOutReceiptMaterial.setProductLineNumber(o.getProductLineNumber());
            wmsOutReceiptMaterial.setUpstreamDocuments(o.getUpstreamDocuments());
            wmsOutReceiptMaterial.setUpstreamNumber(o.getUpstreamNumber());
            wmsOutReceiptMaterial.setUpstreamLineNumber(o.getUpstreamLineNumber());
            wmsOutReceiptMaterial.setOriginalSystemNumber(o.getOriginalSystemNumber());
            wmsOutReceiptMaterial.setOriginalSystemLineNumber(o.getOriginalSystemLineNumber());
            wmsOutReceiptMaterial.setGrossWeight(Objects.isNull(o.getGrossWeight()) ? null : o.getGrossWeight());
            wmsOutReceiptMaterial.setPayableQuantityAssist(o.getOutboundQuantityAssist());
            wmsOutReceiptMaterial.setOutboundQuantityAssist(BigDecimal.ZERO);
            wmsOutReceiptMaterial.setWmsOutReceiptId(null);
            wmsOutReceiptMaterial.setWmsBasicUnitId(o.getWmsBasicUnitId());
            wmsOutReceiptMaterial.setMaterialCode(o.getMaterialCode());
            wmsOutReceiptMaterial.setSpecificationModel(o.getSpecificationModel());
            wmsOutReceiptMaterial.setIsMergeRoll(o.getIsMergeRoll());
            wmsOutReceiptMaterial.setInputBatchCode(o.getInputBatchCode());
            wmsOutReceiptMaterial.setMotherBatchCode(o.getMotherBatchCode());
            wmsOutReceiptMaterial.setPillar(o.getPillar());
            wmsOutReceiptMaterial.setMaterialDirection(o.getMaterialDirection());
            wmsOutReceiptMaterial.setStationNum(o.getStationNum());
            wmsOutReceiptMaterial.setProductModel(o.getSpecificationModel());
            wmsOutReceiptMaterial.setProductType(o.getProductType());
            wmsOutReceiptMaterial.setWmsOutReceiptTaskMaterialId(o.getId());
            return wmsOutReceiptMaterial;
        }).collect(Collectors.toList());
        //自动更新出库单节点
        WorkFlowInfoDto workFlowInfoDto = new WorkFlowInfoDto();
        workFlowInfoDto.setBusinessType("outbound_type");
        workFlowInfoDto.setDocumentType(receiptTask.getDocumentType());
        List<WmsFlowRecord> wmsFlowRecordList = workFlowService.workFlowInfo(workFlowInfoDto);
        if (!CollectionUtil.isEmpty(wmsFlowRecordList)) {
            WmsFlowRecord firstFlowRecord = CollectionUtil.getFirst(wmsFlowRecordList);
            BaseFlowDto lastFlowDto = new BaseFlowDto();
            lastFlowDto.setCode(firstFlowRecord.getFlowCode());
            lastFlowDto.setBusinessType("outbound_type");
            lastFlowDto.setDocumentType(receiptTask.getDocumentType());
            OutBoundReceiptSaveVO saveData= new OutBoundReceiptSaveVO();
            BeanUtil.copyProperties(wmsOutReceipt,saveData);
            saveData.setWmsOutReceiptMaterialList(wmsOutReceiptMaterialList);
            lastFlowDto.setData(saveData);
            workFlowService.commit(lastFlowDto);
        }
    }

    /**
     * 更新任务状态
     */
    public Boolean updateTaskMaterial(String receiptId) {
        boolean taskOutFlag = true;
        WmsOutReceipt wmsOutReceipt = wmsOutReceiptService.getById(receiptId);
        if (Objects.isNull(wmsOutReceipt)) {
            throw new JeecgBootException("出库单不存在!");
        }
        //出库任务id
        String taskId = wmsOutReceipt.getWmsOutReceiptTaskId();
        //出库任务-物料
        List<WmsOutReceiptTaskMaterial> list = wmsOutReceiptTaskMaterialService.list(new LambdaQueryWrapper<WmsOutReceiptTaskMaterial>()
                .eq(WmsOutReceiptTaskMaterial::getWmsOutReceiptTaskId, taskId));
        if (ObjectUtil.isEmpty(list)) {
            throw new JeecgBootException("出库任务无物料明细！");
        }
        WmsOutReceiptTask task = wmsOutReceiptTaskService.getById(taskId);
        for (WmsOutReceiptTaskMaterial taskMaterial : list) {
            LambdaQueryWrapper<WmsOutReceiptMaterial> tempQueryWrapper = new LambdaQueryWrapper<WmsOutReceiptMaterial>()
                    .eq(WmsOutReceiptMaterial::getWmsOutReceiptId, wmsOutReceipt.getId())
                    .eq(WmsOutReceiptMaterial::getWmsBasicMaterialId, taskMaterial.getWmsBasicMaterialId());
            if (!StrUtil.isEmpty(taskMaterial.getBatchCode())) {
                tempQueryWrapper.eq(WmsOutReceiptMaterial::getBatchCode, taskMaterial.getBatchCode());
            }
            List<WmsOutReceiptMaterial> realMaterialList = wmsOutReceiptMaterialService.list(tempQueryWrapper);
            if (!CollectionUtil.isEmpty(realMaterialList)) {
                //如果有这种物料，则比对任务数量和实际出库数量
                WmsOutReceiptMaterial real = realMaterialList.get(0);
                //获取未出库数量
                BigDecimal unoutboundQuantity = taskMaterial.getUnoutboundQuantity();
                if (ObjectUtil.isEmpty(unoutboundQuantity)) {
                    //如果未出库数量为空，默认为计划出库数量
                    unoutboundQuantity = taskMaterial.getPlanQuantity();
                }
                if (unoutboundQuantity.compareTo(real.getOutboundQuantity()) > 0) {
                    taskOutFlag = false;
                } else if (unoutboundQuantity.compareTo(real.getOutboundQuantity()) == 0) {
                    taskOutFlag = true;
                } else {
                    taskOutFlag = true;
                }
            }
        }
        //重新获取更新过的出库任务-物料
        List<WmsOutReceiptTaskMaterial> updatedList = wmsOutReceiptTaskMaterialService.list(new LambdaQueryWrapper<WmsOutReceiptTaskMaterial>()
                .eq(WmsOutReceiptTaskMaterial::getWmsOutReceiptTaskId, taskId));
        boolean anyMatch = updatedList.stream().anyMatch(o -> o.getUnoutboundQuantity().compareTo(BigDecimal.ZERO) != 0);
        if(anyMatch) {
            taskOutFlag=false;
        }
        if (!taskOutFlag) {
            wmsOutReceiptTaskService.update(new LambdaUpdateWrapper<WmsOutReceiptTask>()
                    .set(WmsOutReceiptTask::getOutboundStatus,OutboundStatusEnum.PART.getCode())
                    .eq(WmsOutReceiptTask::getId,taskId)
            );
        }else {
            wmsOutReceiptTaskService.update(new LambdaUpdateWrapper<WmsOutReceiptTask>()
                    .set(WmsOutReceiptTask::getOutboundStatus,OutboundStatusEnum.ALL.getCode())
                    .set(WmsOutReceiptTask::getDocumentStatus,DocumentStatusEnum.COMPLETE.getCode())
                    .eq(WmsOutReceiptTask::getId,taskId)
            );
        }
        return taskOutFlag;
    }
}
